package com.ciaojian.bytedance.service;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ciaojian.core.bytedance.api.ByteDanceRequestApi;
import com.ciaojian.core.bytedance.MiniAppRequestApi;
import com.ciaojian.bytedance.util.Decrypt;
import com.ciaojian.core.bytedance.vo.ByteDanceClientTokenVo;
import com.ciaojian.core.bytedance.vo.ByteMiniAccessToken;
import com.ciaojian.bytedance.vo.bytedance.DyLoginVo;
import com.ciaojian.bytedance.vo.bytedance.UserInfoVo;
import com.ciaojian.core.bytedance.ByteDanceConfig;
import com.ciaojian.core.bytedance.ByteDanceMiniConfig;
import com.ciaojian.core.mapper.DistUserMapper;
import com.ciaojian.core.mapper.UserMapper;
import com.ciaojian.core.model.DistUser;
import com.ciaojian.core.model.User;
import com.ciaojian.core.model.UserError;
import com.ciaojian.core.model.vo.DyUserVo;
import com.ciaojian.core.model.vo.UserLoginInfo;
import com.ciaojian.core.util.JsonUtil;
import com.ciaojian.core.util.RedisUtil;
import com.ciaojian.core.util.Result;
import com.ciaojian.core.util.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 抖音授权服务
 */

@Slf4j
@Service
public class ByteDanceMiniAppAuthService {
    @Resource
    private UserMapper userMapper;


    @Resource
    private DistUserMapper distUserMapper;

    /**
     * 生成 client_token
     * 用于获取接口调用的凭证 client_token。该接口适用于抖音授权。
     */
    public JSONObject getClientToken() {
        Map<String, Object> param = new HashMap<String, Object>();
        //可以设置多个input的name，value
        param.put("client_secret", ByteDanceConfig.CLIENT_SECRET);
        param.put("grant_type", "client_credential");
        param.put("client_key", ByteDanceConfig.CLIENT_KEY);

        //定义接收数据
        JSONObject result = new JSONObject();

        String clientToken = ByteDanceRequestApi.sendRequest(MiniAppRequestApi.CLIENT_TOKEN, param);

        ByteDanceClientTokenVo byteDanceClientTokenVo = JsonUtil.fromData(clientToken, ByteDanceClientTokenVo.class);

        RedisUtil.setKeyTime("BYTEDANCE_CLIENTTOKEN", 7200, byteDanceClientTokenVo.getData().getAccess_token(), DateUnit.SECOND);

        result = JSON.parseObject(clientToken);
        return result;
    }


    /**
     * 获取 access_token
     */
    public JSONObject getAccessToken(String code) {
        Map<String, Object> param =  new HashMap<String, Object>();

        //可以设置多个input的name，value
        param.put("client_secret", ByteDanceConfig.CLIENT_SECRET);
        param.put("code", code);
        param.put("grant_type", "authorization_code");
        param.put("client_key", ByteDanceConfig.CLIENT_KEY);
        //定义接收数据
        JSONObject result = new JSONObject();

        String accessToken = ByteDanceRequestApi.sendRequest(MiniAppRequestApi.ACCESS_TOKEN, param);
        result= JSON.parseObject(accessToken);

        return result;
    }

    /**
     *  getAccessToken /v2/token
     */
    public ByteMiniAccessToken authMiniApp() {
        JSONObject param = new JSONObject();
        param.put("appid", ByteDanceMiniConfig.APP_ID);
        param.put("secret", ByteDanceMiniConfig.SECRET_ID);
        param.put("grant_type", "client_credential");
        //定义接收数据
        JSONObject result = new JSONObject();

        String access_token_v2 = ByteDanceRequestApi.sendRequest(MiniAppRequestApi.ACCESS_TOKEN_V2, param);

        result = JSON.parseObject(access_token_v2);
        ByteMiniAccessToken byteMiniAccessToken = result.toJavaObject(ByteMiniAccessToken.class);
        return byteMiniAccessToken;
    }

    /**
     * 用户授权，把用户信息保存，并且登录
     * @param dyLoginVo
     * @return
     */
    public JSONObject login(DyLoginVo dyLoginVo) {
        JSONObject param = new JSONObject();
        param.put("appid", ByteDanceMiniConfig.APP_ID);
        param.put("secret", ByteDanceMiniConfig.SECRET_ID);
        param.put("anonymous_code", dyLoginVo.getAnonymousCode());
        param.put("code", dyLoginVo.getCode());
        //定义接收数据
        JSONObject result = new JSONObject();
        String code2session = ByteDanceRequestApi.sendRequest(MiniAppRequestApi.CODE2SESSION, param);
        result = JSON.parseObject(code2session);
        return result;
    }

    public Result saveUserInfo(DyUserVo dyUserVo) {
        if(ObjectUtil.isNotNull(dyUserVo.getEncryptedData())){
            try {
                String decrypt = Decrypt.decrypt(dyUserVo.getEncryptedData(), dyUserVo.getSession_key(), dyUserVo.getIv());
                UserInfoVo userInfoVo = JsonUtil.fromJson(decrypt, UserInfoVo.class);
                dyUserVo.setTelphone(userInfoVo.getPhoneNumber());
            }catch (Exception e){}
        }

        if (ObjectUtil.isNull(dyUserVo.getTelphone())) {
            return Result.error("手机号不能为空");
        }
        if (ObjectUtil.isNull(dyUserVo.getOpenid())) {
            return Result.error("openid不能为空");
        }
        User user;
        String token = TokenUtil.makeToken(dyUserVo.getOpenid());
        HashMap<String, Object> map = new HashMap<>(2);
        map.put("token", token);
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("telphone", dyUserVo.getTelphone());
        user = userMapper.selectOne(userQueryWrapper);
        try {
            if (ObjectUtil.isNotNull(user)) {
                if (ObjectUtil.isNull(user.getDyAddTime())) {
                    user.setDyAddTime(new Date());
                }
                user.setDy(true);
                user.setUpdateTime(new Date());
                user.setDyOpenid(dyUserVo.getOpenid());
                user.setDyUnionid(dyUserVo.getUnionid());
                user.setTelphone(dyUserVo.getTelphone());
                if(ObjectUtil.isNotNull(dyUserVo.getNickName())){
                    user.setDyNickName(dyUserVo.getNickName());
                }else {
                    user.setDyNickName("抖音用户");
                }

                if(ObjectUtil.isNotNull(dyUserVo.getAvatarUrl())){
                    user.setDyAvatarUrl(dyUserVo.getAvatarUrl());
                }else {
                    user.setDyAvatarUrl("https://www.ciaojian.com/img/file/1.png");
                }
                userMapper.updateById(user);
                userQueryWrapper.eq("dy_openid", dyUserVo.getOpenid());
                User newUser = userMapper.selectOne(userQueryWrapper);
                map.put("user", newUser);
                map.put("userLoginInfo", loginSuccess(newUser.getId()));
                return Result.ok(newUser);
            } else {
                QueryWrapper<User> userqw = new QueryWrapper<>();
                userqw.eq("dy_openid", dyUserVo.getOpenid());
                user = userMapper.selectOne(userqw);

                if (ObjectUtil.isNotNull(user)) {
                    if (ObjectUtil.isNull(user.getDyAddTime())) {
                        user.setDyAddTime(new Date());
                    }
                    user.setDy(true);
                    user.setUpdateTime(new Date());
                    user.setTelphone(dyUserVo.getTelphone());
                    user.setDyOpenid(dyUserVo.getOpenid());
                    user.setDyUnionid(dyUserVo.getUnionid());
                    if(ObjectUtil.isNotNull(dyUserVo.getNickName())){
                        user.setDyNickName(dyUserVo.getNickName());
                    }else {
                        user.setDyNickName("抖音用户");
                    }

                    if(ObjectUtil.isNotNull(dyUserVo.getAvatarUrl())){
                        user.setDyAvatarUrl(dyUserVo.getAvatarUrl());
                    }else {
                        user.setDyAvatarUrl("https://www.ciaojian.com/img/file/1.png");
                    }
                    userMapper.updateById(user);
                    userQueryWrapper.eq("dy_openid", dyUserVo.getOpenid());
                    User newUser = userMapper.selectOne(userQueryWrapper);
                    map.put("user", newUser);
                    map.put("userLoginInfo", loginSuccess(newUser.getId()));

                    return Result.ok(newUser);
                } else {
                    user = new User();
                    user.setTelphone(dyUserVo.getTelphone());
                    user.setDy(true);
                    user.setUpdateTime(new Date());
                    user.setDyAddTime(new Date());
                    user.setDyOpenid(dyUserVo.getOpenid());
                    user.setDyUnionid(dyUserVo.getUnionid());
                    if(ObjectUtil.isNotNull(dyUserVo.getNickName())){
                        user.setDyNickName(dyUserVo.getNickName());
                    }else {
                        user.setDyNickName("抖音用户");
                    }

                    if(ObjectUtil.isNotNull(dyUserVo.getAvatarUrl())){
                        user.setDyAvatarUrl(dyUserVo.getAvatarUrl());
                    }else {
                        user.setDyAvatarUrl("https://www.ciaojian.com/img/file/1.png");
                    }
                    Integer id = userMapper.maxId();
                    id++;
                    user.setId(id);
                    try {
                        userMapper.insert(user);
                    }catch (Exception e){
                        id = id+3;
                        user.setId(id);
                        userMapper.insert(user);
                    }
//                userService.invited(invitedId, newUserA.getId());
                    userQueryWrapper.eq("dy_openid", dyUserVo.getOpenid());
                    User newUser = userMapper.selectOne(userQueryWrapper);
                    map.put("user", newUser);
                    map.put("userLoginInfo", loginSuccess(newUser.getId()));

                    return Result.ok(newUser);
                }

            }

        }catch (Exception e){
            if (ObjectUtil.isNotNull(user)) {
                insertUserError(dyUserVo.getOpenid(), e.getMessage(), user.getId(), dyUserVo.getTelphone());
            }else {
                insertUserError(dyUserVo.getOpenid(), e.getMessage(), 0, dyUserVo.getTelphone());
            }
        }
        return Result.error("系统异常");
    }

    /**
     * 登录成功返回登录信息
     *
     * @param uid 用户ID
     * @return 登录信息
     */
    public UserLoginInfo loginSuccess(Integer uid) {
        UserLoginInfo userLoginInfo = new UserLoginInfo();
        QueryWrapper<DistUser> distUserQueryWrapper = new QueryWrapper<>();
        distUserQueryWrapper.eq("user_id",uid);
        DistUser distUser = distUserMapper.selectOne(distUserQueryWrapper);

        userLoginInfo.setUserId(uid);
        userLoginInfo.setDistUser(distUser);
        return userLoginInfo;
    }

    /**
     * 错误登录用户写入
     */
    public void insertUserError(String openid, String message, Integer id, String telphone){
        UserError userError = new UserError();
        userError.setOpenid(openid);
        userError.setDate(new Date());
        userError.setMsg(message);
        userError.setType("抖音");
        userError.setUserId(id);
        userError.setTelphone(telphone);
        userError.insert();
    }

    public Result getUserBydyopenid(String dyOpenid) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("dy_openid",dyOpenid);
        User user = userMapper.selectOne(userQueryWrapper);

        if(ObjectUtil.isNull(user)){
            return Result.error("无用户信息,请先登录");
        }
        String token = TokenUtil.makeToken(user.getOpenid());
        user.setToken(token);

        return Result.ok(user);

    }

    public Result userPortrait(DyUserVo dyUserVo) {
        User user = userMapper.selectById(dyUserVo.getId());

        if(ObjectUtil.isNotNull(dyUserVo.getNickName())){
            user.setDyNickName(dyUserVo.getNickName());
        }else {
            user.setDyNickName("抖音用户");
        }

        if(ObjectUtil.isNotNull(dyUserVo.getAvatarUrl())){
            user.setDyAvatarUrl(dyUserVo.getAvatarUrl());
        }else {
            user.setDyAvatarUrl("https://www.ciaojian.com/img/file/1.png");
        }
        user.updateById();
        return Result.ok(user);
    }
}
